using System;
using System.Collections;
using System.IO;
using System.Reflection;
using EnvDTE;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.TestTools.Common;
using System.Globalization;
using System.Collections.Generic;

namespace NUnitForVSTS.NUnitTest
{
    /// <summary>
    /// Explorer for the source files
    /// </summary>
	class SourceFileExplorer
	{
        /// <summary>
        /// Reads the specified location.
        /// </summary>
        /// <param name="location">The location.</param>
        /// <param name="projectData">The project data.</param>
        /// <param name="warningHandler">The warning handler.</param>
        /// <returns></returns>
		public ICollection Read(string location, ProjectData projectData, IWarningHandler warningHandler)
		{
			ICollection result = new List<ITestElement>();
			AppDomain testLoaderDomain = null;
			try
			{
				DTE dte = (DTE)Package.GetGlobalService(typeof(DTE));
				IVsSolution solution = (IVsSolution)Package.GetGlobalService(typeof(SVsSolution));

                AppDomainSetup domainSetup = new AppDomainSetup();

                string codeBase = Path.GetDirectoryName(GetType().Assembly.Location);
                domainSetup.ApplicationBase = codeBase;

                //domainSetup.LoaderOptimization = AppDomain.CurrentDomain.SetupInformation.LoaderOptimization;
                domainSetup.ShadowCopyFiles = "true";

                Type explorerType = typeof(NUnitTestFileExplorer);
                testLoaderDomain = AppDomain.CreateDomain("EnumerateDomain:" + Guid.NewGuid().ToString(), explorerType.Assembly.Evidence, domainSetup);

                //Using Full paths because Application base isn't the visual studio location
                //string vsLocation = Path.GetDirectoryName(Path.GetDirectoryName(typeof(TestElement).Assembly.Location));

                //string privateAssemblyLocation = Path.Combine(vsLocation, "PrivateAssemblies");
                //string publicAssemblyLocation = Path.Combine(vsLocation, "PublicAssemblies");
                //string[] directories = { privateAssemblyLocation, publicAssemblyLocation, vsLocation, codeBase, AppDomain.CurrentDomain.BaseDirectory, Path.GetDirectoryName(typeof(NUnitTestFileExplorer).Assembly.Location), location };
                //using (AssemblyResolver resolver = (AssemblyResolver)testLoaderDomain.CreateInstanceFromAndUnwrap(typeof(AssemblyResolver).Assembly.Location, typeof(AssemblyResolver).FullName, false, BindingFlags.Default, null, new object[] { directories }, null, null, null))
                //{
                NUnitTestFileExplorer explorer = ((NUnitTestFileExplorer)testLoaderDomain.CreateInstanceAndUnwrap(explorerType.Assembly.FullName, explorerType.FullName));
                result = explorer.Read(dte, solution, location, projectData, warningHandler);
                //}
                AppDomain.Unload(testLoaderDomain);
			}
			catch(Exception e)
			{
				warningHandler.Write(this, new WarningEventArgs(e.ToString()));
				//throw;
			}
			return result;
		}
	}
}
